package com.dingreading.cloud.admin.controller;

import com.dingreading.cloud.admin.entity.WhStockIn;
import com.dingreading.cloud.admin.entity.WhStockOutGoods;
import com.dingreading.cloud.admin.entity.WhStockOutGoodsLog;
import com.dingreading.cloud.admin.service.*;
import com.dingreading.cloud.admin.util.bean.GoodsWetAvgUtil;
import com.dingreading.cloud.admin.util.bean.PurchaseUtil;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

@RestController
@RequestMapping("/system/whStockOutGoods")
@Api(tags = "总部-仓库出库商品记录管理")
public class WhStockOutGoodsController {

    @Resource
    protected WhStockInService whStockInService;
    @Resource
    protected GoodsTypeService goodsTypeService;
    @Resource
    protected WhStockOutService whStockOutService;
    @Resource
    protected WhStockOutGoodsService whStockOutGoodsService;
    @Resource
    protected WhStockOutGoodsLogService whStockOutGoodsLogService;
    @Resource
    protected ShopCartService shopCartService;

    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList", produces = "application/json; charset=UTF-8")
    public R<Object> pageList(
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "商品订单号/出库订单号/商品名/商品规格名") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "是否实体 1.实体 0.不是") @RequestParam(value = "realStatus", required = false) Integer realStatus,
            @ApiParam(value = "出库方式 1.自营仓库 2.线上发货 3.第三方仓库") @RequestParam(value = "stockOutMethod", required = false) Integer stockOutMethod,
            @ApiParam(value = "状态 -1.出库退回 0.已取消 1.出库完成 2.保存") @RequestParam(value = "status", required = false) Integer status,
            @ApiParam(value = "活动开始日期") @RequestParam(value = "beginDate", required = false) String beginDate,
            @ApiParam(value = "活动结束日期") @RequestParam(value = "endDate", required = false) String endDate
    ) {
        Page<WhStockOutGoods> page = this.whStockOutGoodsService.pageList(pageUtil, keyword, status, realStatus, stockOutMethod, beginDate, endDate);

        PageBeanDto data = new PageBeanDto();
        data.setTotal(page.getTotalRow());
        data.setList(page.getRecords());
        return R.ok(data);
    }


    @ApiOperation(value = "删除")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "出库订单号") @RequestParam(value = "outCode") String outCode,
            @ApiParam(value = "出库商品记录id") @RequestParam(value = "id") Long id
    ) {
        long l = whStockOutGoodsService.dropByOutCodeAndId(outCode, id);
        if (l <= 0) return R.fail("删除失败");

        // 更新出库单的商品规格总数和出库总数
        List<WhStockOutGoods> outGoodsList = whStockOutGoodsService.getByOutCode(outCode);
        Set<Long> shopCartIds = new HashSet<>();
        int numCnt = 0;
        if (CollectionUtils.isNotEmpty(outGoodsList)) {
            for (WhStockOutGoods whStockOutGoods : outGoodsList) {
                Long shopCartId = whStockOutGoods.getShopCartId();
                shopCartIds.add(shopCartId);
                numCnt += NepUtil.nullToZero(whStockOutGoods.getNum());
            }
        }
        whStockOutService.updateGoodsTypeNumAndNum(outCode, shopCartIds.size(), numCnt);

        return R.ok();
    }


    @ApiOperation(value = "出库商品记录退回")
    @PostMapping(value = "/returnOutGoods", produces = "application/json; charset=UTF-8")
    public R<Object> returnOutGoods(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "出库订单号") @RequestParam(value = "outCode") String outCode,
            @ApiParam(value = "出库商品记录id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "退回备注") @RequestParam(value = "remark") String remark
    ) throws Exception {
        WhStockOutGoods outGoods = whStockOutGoodsService.getByOutCodeAndId(outCode, id);
        if (outGoods == null) return R.fail("商品出库记录获取失败");
        if (!outGoods.getStatus().equals(1)) return R.fail("商品出库记录的状态不是 出库完成");

        List<WhStockOutGoodsLog> logList = whStockOutGoodsLogService.getOutGoodsLog(outGoods.getOrderCode(), outGoods.getOutCode(),
                outGoods.getShopCartId(), outGoods.getGoodsTypeId());
        if (CollectionUtils.isEmpty(logList)) return R.fail("商品出库关联的消耗记录获取失败");

        List<Long> updateLogIds = new ArrayList<>();
        List<String> inCodes = new ArrayList<>();
        Map<String, Integer> inMap = new HashMap<>();
        for (WhStockOutGoodsLog log : logList) {
            updateLogIds.add(log.getId());
            // 入库订单号
            String inCode = log.getInCode();
            inCodes.add(inCode);
            // 出库商品数量
            Integer num = NepUtil.nullToZero(log.getNum());
            inMap.put(inCode, num);
        }

        List<WhStockIn> inList = whStockInService.getByInCodes(inCodes);
        if (CollectionUtils.isEmpty(inList)) return R.fail("出库消耗的入库记录获取失败");

        // 商品出库时的加权平均价
        double wetAvgPrice = NepUtil.nullToZero(outGoods.getWetAvgPrice());
        int numCnt = NepUtil.nullToZero(outGoods.getNum());
        // 重新入库
        Date time = DateUtil.getNowDatetime();
        List<WhStockIn> newList = new ArrayList<>();
        for (WhStockIn stockIn : inList) {
            // 获取退回消耗的入库数量
            Integer num = inMap.get(stockIn.getInCode());
            // 新建出库退回的入库记录
            WhStockIn newData = PurchaseUtil.returnNewStockIn(headStaffUid, headStaffName, stockIn, id, num, wetAvgPrice, time);
            newList.add(newData);
        }

        boolean r = whStockOutGoodsService.setRefund(outCode, id, headStaffUid, headStaffName, remark, time);
        if (!r) throw new Exception("出库商品退回失败");
        boolean l = whStockOutGoodsLogService.setRefund(updateLogIds, headStaffUid, headStaffName, time);
        if (!l) throw new Exception("出库商品的消耗记录退回失败");
        // 保存入库记录
        whStockInService.saveOrUpdateBatch(newList);
        // 退回后重新入库成功，更新入库商品的加权平均价
        double inAmount = DoubleUtil.mul(wetAvgPrice, numCnt);
        GoodsWetAvgUtil.updateGoodsWetAvgPrice(outGoods.getGoodsName() + "-" + outGoods.getGoodsTypeName(), outGoods.getGoodsId(),
                outGoods.getGoodsTypeId(), outGoods.getNum(), inAmount);

        return R.ok();
    }

}